<template>
  <div class="calender-container">
    <!-- 自定义头部，切换视图类型和切换日期 -->
    <div class="calender-header mb2">
      <div class="header-center">
        <el-icon circle @click="changeDateRange('prev')"><ArrowLeftBold /></el-icon>
        <span class="time-title">{{ currentDate }}</span>
        <el-icon @click="changeDateRange('next')"><ArrowRightBold /></el-icon>
        <!-- <el-icon circle @click="Tcalendar.prev(), dayTime()"><ArrowLeftBold /></el-icon>
        <span class="time-title">{{ currentDate }}</span>
        <el-icon @click="Tcalendar.next(), dayTime()"><ArrowRightBold /></el-icon> -->
      </div>
      <div class="header-right">
        <!-- 回到今天 -->
        <!-- <el-button class="btn-m2" type="primary" @click="Tcalendar.today(), dayTime()" plain round>今天</el-button> -->
        <!-- <el-select v-model="type" placeholder="视图类型" style="width: 80px" @change="changeType">
            <el-option label="月" value="dayGridMonth" />
            <el-option label="周" value="timeGridWeek" />
            <el-option label="天" value="timeGridDay" />
            <el-option label="列" value="listWeek" />
          </el-select> -->
        <!-- 日期选择 -->
        <!-- <el-date-picker
          v-if="type === 'dayGridMonth'"
          v-model="showMonth"
          type="month"
          :clearable="false"
          placeholder="请选择日期"
          style="margin-left: 10px; vertical-align: middle"
          @change="changeDate" /> -->
        <!-- <el-button class="ml2" type="primary" :icon="Plus" plain>新增排班</el-button> -->
      </div>
    </div>
    <div ref="fullcalendar"></div>
    <span ref="triggerRef" class="trigger"></span>
    <el-popover
      popper-class="more-operation-popover"
      :visible="popoverVisible"
      :virtual-ref="triggerRef"
      trigger="click"
      virtual-triggering>
      <div class="btn" @click="editCalendar">修改日期</div>
    </el-popover>
    <!-- 查看任务详情弹窗 -->
    <!-- <CalendarDetailDialog
      v-model:dialogVisible="calendarDialogVisible"
      :detailInfo="detailInfo"
      :getStatus="getStatus" /> -->
    <TaskChatDialog
      v-model="calendarDialogVisible"
      width="1200px"
      class="task-dialog"
      :title="taskDialogTitle"
      append-to-body
      body-class-name="dialog-custom"
      destroy-on-close
      :close-on-click-modal="false">
      <TaskDetail :task="taskData" :show-message="showMessage" :allow-operations="true"></TaskDetail>
    </TaskChatDialog>
    <!-- 新增任务弹窗 -->
    <!-- <DrawerAddPlan v-model:drawerVisile="drawerVisile" :addTaskInfo="addTaskInfo" /> -->
    <CalendarAddDialog :drawerVisile="drawerVisile" :addTaskInfo="addTaskInfo" @closeDialog="closeDialog" />
  </div>
</template>

<script setup>
import { Calendar } from '@fullcalendar/core'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import listPlugin from '@fullcalendar/list'
import interactionPlugin from '@fullcalendar/interaction'
import dayjs from 'dayjs'
import { ArrowLeftBold, ArrowRightBold, Plus } from '@element-plus/icons-vue'
import { getTaskListByTime, getTaskDetail } from '@/assets/api/task'
import useEventBus from '@/use/use-event-bus.js'
import { ElMessage, ClickOutside as vClickOutside } from 'element-plus'
const eventBus = useEventBus()
import useProject from '@/store/project'
import { nextTick, onUnmounted } from 'vue'
const projectStore = useProject()

const props = defineProps({
  calendarData: {
    type: Object,
    default: () => {},
  },
  disabled: {
    type: Boolean,
    default: false,
  },
})

const infoList = ref([])
const queryDateParam = ref({
  start: dayjs().startOf('month').format('YYYY-MM-DD'),
  end: dayjs().endOf('month').format('YYYY-MM-DD'),
})

const fullcalendar = ref()
const Tcalendar = ref()
const type = ref('dayGridMonth') // 默认月视图
const currentDate = ref() // 当前时间
const showMonth = ref(dayjs().format('YYYY-MM')) // 默认当前月份
const calendarDialogVisible = ref(false) // 是否显示详情弹窗
const detailInfo = ref() // 详情数据
const addTaskInfo = ref() // 详情数据
const drawerVisile = ref(false) // 是否显示新增排班的抽屉
// const calendarData = inject('taskInfo')
const editTaskInfo = ref({})
const controller = new AbortController()
const { signal } = controller

const initCalendar = () => {
  Tcalendar.value = new Calendar(fullcalendar.value, {
    plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
    initialView: type.value,
    // validRange: function () {
    //   const today = new Date()
    //   const start = new Date(today.getFullYear(), today.getMonth(), 1)
    //   const end = new Date(today.getFullYear(), today.getMonth() + 1, 0)
    //   return { start, end }
    // },
    aspectRatio: 2.2, // 宽度比
    locale: 'zh-cn',
    // handleWindowResize: true,
    //   loading: loading //控制表格加载
    editable: true, // 允许编辑表格
    // droppable: true, //允许从外部拖拽进入日历
    // eventDurationEditable: true, //控制时间段是否可以拖动
    // eventResizableFromStart: true, //控制事件是否可以拖动
    selectable: true, // 允许用户通过单击和拖动来突出显示多个日期或时间段
    firstDay: 1, // 设置一周中显示的第一天是哪天，周日是0，周一是1，类推。
    unselectAuto: true, // 当点击页面日历以外的位置时，是否自动取消当前的选中状态
    dayMaxEvents: 3, //在dayGrid视图中，给定日期内的最大事件数
    eventMaxStack: 3,
    moreLinkContent: '+ 更多',
    headerToolbar: false, // 关闭默认日历头部，采取自定义的方式切换日历视图
    // allDaySlot: false, // 关闭全天选项
    allDayText: '全天',
    nowIndicator: true,
    events: infoList.value, //主要数据
    eventBorderColor: 'transparent',
    weekends: true,
    eventClassNames: function (arg) {
      // 添加自定义class
      return [arg.event.extendedProps.class]
    },
    eventContent: function (arg) {
      // 日历上event显示的样式
      const italicEl = document.createElement('div')

      // 列表才显示
      if (type.value === 'listWeek') {
        // 标题
        const nameEl = document.createElement('h4')
        nameEl.setAttribute('class', `h4`)
        nameEl.innerHTML = arg.event.extendedProps.name
        italicEl.append(nameEl)
        // 岗位
        const text1El = document.createElement('p')
        text1El.innerHTML = arg.event.extendedProps.job
        italicEl.append(text1El)
        // 面试官
        const text2El = document.createElement('p')
        text2El.innerHTML = '描述：' + arg.event.extendedProps.job
        italicEl.append(text2El)
      } else {
        // 标题
        const titleEl = document.createElement('div')
        const circleEl = document.createElement('div')
        titleEl.setAttribute('class', `calendar-title`)
        circleEl.setAttribute('class', `calendar-circle circle-${arg.event.extendedProps.taskPriority}`)

        // 时间
        const taskEl = document.createElement('span')
        if (arg.event.start && arg.event.end) {
          let title = arg.event.extendedProps.taskTitle
          let status = arg.event.extendedProps.currentStatus
          let completePercent = arg.event.extendedProps.completePercent
          const taskContent = `<span>${title}</span>
          <span style="color: ${getStatus(status, 'color')};">${getStatus(status, 'text')}</span>
          <span style="color: var(--task-underway-color);">${status === 2 ? completePercent + '%' : ''}</span>`
          taskEl.innerHTML = taskContent
          titleEl.append(taskEl)
        }
        italicEl.append(circleEl)
        italicEl.append(titleEl)
      }
      italicEl.setAttribute('class', `calendar-card`)
      return { domNodes: [italicEl] }
    },
    noEventsContent: function () {
      const noEl = document.createElement('div')
      noEl.innerHTML = '暂无日程安排，请安排相关日程'
      return { domNodes: [noEl] }
    },
    eventDidMount: function (arg) {
      const calendarDialog =
        document.getElementsByClassName('calendar-dialog')[0] ||
        document.getElementsByClassName('calender-container')[0]
      if (calendarDialog) {
        calendarDialog.addEventListener(
          'click',
          (e) => {
            editTaskInfo.value = {}
            popoverVisible.value = false
          },
          { signal }
        )
        arg.el.addEventListener(
          'contextmenu',
          (e) => {
            e.preventDefault()
            if (arg.event.extendedProps.currentStatus !== 1) {
              ElMessage.warning('当前该任务不是未开始状态，无法编辑')
              return
            }
            popoverVisible.value = false
            editTaskInfo.value = {
              ...arg.event.extendedProps,
              startStr: dayjs(arg.event.extendedProps.planBegintime).format('YYYY-MM-DD'),
              endStr: dayjs(arg.event.extendedProps.planEndtime).format('YYYY-MM-DD'),
            }
            triggerRef.value.style.top = e.clientY + 'px'
            triggerRef.value.style.left = e.clientX + 'px'
            nextTick(() => {
              popoverVisible.value = true
            })
          },
          { signal }
        )
      }
    },
    // 点击查看时触发
    eventClick: function (info) {
      handleClick(info)
    },
    // 视图选择日期触发
    select: function (info) {
      info.endStr = dayjs(info.endStr).subtract(1, 'day')
      if (!props.disabled) {
        handleSelectDate(info)
      }
    },
    // 设置单击事件的处理函数
    dateClick: function (info) {
      handleDateClick(info)
    },
    // 拖拽event大小时触发
    eventResize: function (info) {
      handleEventResize(info)
    },
    // 拖拽停止时触发
    eventDrop: function (info) {
      handleDrop(info)
    },
  })
  Tcalendar.value.render()
}

const popoverVisible = ref(false)
const triggerRef = ref()

function editCalendar() {
  popoverVisible.value = false
  handleSelectDate(editTaskInfo.value)
}

// 事件日期调整
const handleSelectDate = (info) => {
  if (dateValidate(info)) {
    addTaskInfo.value = info
    drawerVisile.value = true
  }
}

// 事件拖拽
const handleDrop = (info) => {
  if (dateValidate(info.event)) {
    addTaskInfo.value = {
      startStr: dayjs(info.event.startStr).format('YYYY-MM-DD'),
      endStr: dayjs(info.event.endStr).format('YYYY-MM-DD'),
      ...info.event.extendedProps,
    }
    drawerVisile.value = true
  } else {
    resetCalendar()
  }
}

// 日期验证
const dateValidate = (info) => {
  let currentStatus = info.extendedProps?.currentStatus
  // let reduceEndTime = dayjs(info.endStr).subtract(1, 'day').format('YYYY-MM-DD')
  // let reduceEndTime = dayjs(info.endStr).format('YYYY-MM-DD')
  // let ruleStart = dayjs(props.calendarData.start).format('YYYY-MM-DD')
  // let ruleEnd = dayjs(props.calendarData.end).format('YYYY-MM-DD')
  // let timeStart = dayjs(info.startStr).format('YYYY-MM-DD') + ' 00:00:01'
  // let timeEnd = reduceEndTime + ' 23:59:58' //减少一秒
  //判断开始时间是否在规定范围内
  // const isWithinRangeStart = dayjs(timeStart).isBetween(props.calendarData.start, props.calendarData.end)
  //判断结束时间是否在规定范围内
  // const isWithinRangeEnd = dayjs(timeEnd).isBetween(props.calendarData.start, props.calendarData.end)

  // if (!isWithinRangeStart) {
  //   ElMessage.warning(`未在规定范围内${ruleStart}至${ruleEnd}`)
  //   return false
  // }
  // if (!isWithinRangeEnd) {
  //   ElMessage.warning(`未在规定范围内${ruleStart}至${ruleEnd}`)
  //   return false
  // }
  // if (!isWithinRangeStart && !isWithinRangeEnd) {
  //   ElMessage.warning(`未在规定范围内${ruleStart}至${ruleEnd}`)
  //   return false
  // }
  if (currentStatus && currentStatus !== 1) {
    ElMessage.warning('当前该任务不是未开始状态，无法编辑')
    return false
  }
  return true
}

function getStatus(status, type) {
  let statusObj = {
    color: '',
    text: '',
  }
  switch (parseInt(status)) {
    case 1:
      statusObj = {
        color: 'var(--task-default-color)',
        text: '未开始',
      }
      break
    case 2:
      statusObj = {
        color: 'var(--task-underway-color)',
        text: '进行中',
      }
      break
    case 4:
      statusObj = {
        color: 'var(--task-finish-color)',
        text: '已完成',
      }
      break
  }
  if (type === 'text') {
    return statusObj.text
  } else {
    return statusObj.color
  }
}

/**
 * 获取当前时间
 */
const dayTime = () => {
  if (type.value === 'dayGridMonth') {
    currentDate.value = dayjs(Tcalendar.value.getDate()).format('YYYY年MM月')
    // showMonth.value = dayjs(Tcalendar.value.getDate()).format('YYYY-MM');
  } else if (type.value === 'timeGridWeek' || type.value === 'listWeek') {
    currentDate.value =
      dayjs(Tcalendar.value.getDate()).format('YYYY年MM月DD日') +
      ' - ' +
      dayjs(Tcalendar.value.getDate()).add(6, 'day').format('DD日')
  } else if (type.value === 'timeGridDay') {
    currentDate.value = dayjs(Tcalendar.value.getDate()).format('YYYY年MM月DD日')
  }
}

/**
 * 拖拽调整大小时触发
 */
const handleEventResize = (info) => {
  console.log('info2--', info)
}

/**
 * 点击事件，查看任务详情
 */
const taskData = ref({})
const showMessage = ref(false)
const handleClick = (info) => {
  getDetail(info.event.extendedProps.taskId)
}

async function getDetail(id) {
  getTaskDetail(id).then((res) => {
    if (res.code === 200) {
      taskData.value = res.data
      calendarDialogVisible.value = true
    } else {
      ElMessage.error(res.msg)
    }
  })
}

const taskDialogTitle = computed(() => {
  if (taskData.value.taskTitle) {
    const { projectName, itemName, taskTitle, taskCode } = taskData.value
    return `${projectName}/${itemName}/${taskTitle}-#${taskCode}`
  }
  return ''
})

const closeDialog = () => {
  drawerVisile.value = false
  resetCalendar()
}

const resetCalendar = () => {
  const events = Tcalendar.value.getEventSources()
  events[0].remove()
  Tcalendar.value.addEventSource(infoList.value)
}

//   切换类型
const changeType = (type) => {
  Tcalendar.value.changeView(type)
  dayTime()
}

const handleDateClick = (info) => {
  // console.log('info5--', info)
}

/**
 * 修改月份
 * @param date 跳转日期
 */
const changeDate = (date) => {
  Tcalendar.value.gotoDate(dayjs(date).format('YYYY-MM'))
  currentDate.value = dayjs(date).format('YYYY年MM月')
}

eventBus.on('updateSelectDate', (data, type) => {
  if (type === 'edit') {
    getTaskListByTimeData()
  }
})

const dateRange = ref({
  planBegintime: dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss'),
  planEndtime: dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss'),
})

function changeDateRange(dateType) {
  if (type.value === 'dayGridMonth') {
    dateType === 'prev' ? Tcalendar.value.prev() : Tcalendar.value.next()
    dateRange.value.planBegintime = dayjs(Tcalendar.value.getDate()).startOf('month').format('YYYY-MM-DD HH:mm:ss')
    dateRange.value.planEndtime = dayjs(Tcalendar.value.getDate()).endOf('month').format('YYYY-MM-DD HH:mm:ss')
    getTaskListByTimeData()
  }
  dayTime()
}

function getTaskListByTimeData() {
  getTaskListByTime({
    projectId: projectStore.getProjectInfo.projectId,
    taskUserId:
      props.calendarData?.taskUserId && props.calendarData?.taskUserId > 0 ? props.calendarData.taskUserId : '',
    planBegintime: dateRange.value.planBegintime,
    planEndtime: dateRange.value.planEndtime,
  }).then((res) => {
    if (res.code === 200) {
      infoList.value = res.data.tcTaskInfos.map((item) => {
        return {
          ...item,
          id: item.taskId,
          start: `${item.planBegintime} 00:00:00`,
          end: item.currentEndTime ? `${item.currentEndTime} 23:59:59` : `${item.planEndtime} 23:59:59`,
          class: `tag_${item.taskPriority} ${props.calendarData?.taskId === item.taskId ? 'active' : ''}`,
        }
      })
      if (Tcalendar.value) {
        resetCalendar()
      } else {
        initCalendar()
      }
      dayTime()
    } else {
      ElMessage.error(res.msg)
    }
  })
}

onMounted(() => {
  getTaskListByTimeData()
})
onUnmounted(() => {
  controller.abort()
})
</script>

<style lang="scss" scoped>
.calender-header {
  // display: flex;
  // justify-content: space-between;
  @include use-flex(center, center);
  .header-center {
    display: flex;
    align-items: center;
    .elp-icon {
      cursor: pointer;
    }
    .time-title {
      font-weight: bold;
      font-size: 20px;
      margin: 0 20px;
    }
  }
}
.btn-m2 {
  margin-right: 20px;
}
.ml2 {
  margin-left: 20px !important;
}
.mb2 {
  margin-bottom: 20px !important;
}

:deep(.fc) {
  .fc-event {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .fc-col-header-cell {
    padding: 12px 0;
    box-sizing: border-box;
  }
  .fc-scrollgrid {
    border-left: none;
    border-top: none;
    .fc-scrollgrid-section {
      td {
        border-bottom: none;
      }
    }
  }
  .fc-daygrid-day-top {
    justify-content: center;
  }
  th,
  td {
    border-right: none;
    border-left: none;
  }
  .fc-daygrid-day.fc-day-today {
    background-color: transparent;
    .fc-daygrid-day-number {
      background-color: #ff9000;
      color: #fff;
      border-radius: 50%;
    }
  }
  .fc-highlight {
    background: rgba(24, 181, 82, 0.1);
  }
  .fc-timegrid-col.fc-day-today {
    background-color: rgba(101, 180, 230, 0.2);
  }
  .fc-popover {
    z-index: 99;
  }
  .fc-popover-header {
    background-color: var(--elp-bg-color);
  }
  .fc-popover-body {
    .fc-daygrid-event-harness {
      margin: 5px 0;
    }
  }

  // .fc-day-future.fc-day-other {
  //   display: none;
  // }
}

:deep(.calendar-card) {
  display: block;
  padding: 0px 4px;
  border: none;
  color: var(--elp-text-color-primary);
  @include use-flex(center, flex-start);
  .calendar-title {
    margin-left: 7px;
    line-height: 15px;
    height: 15px;
    span {
      margin-right: 5px;
      font-weight: bold;
      font-size: 12px;
    }
  }
  .calendar-circle {
    width: 6px;
    height: 6px;
    border-radius: 50%;
  }
  .circle-1 {
    background-color: var(--elp-color-danger);
  }
  .circle-2 {
    background-color: var(--elp-color-warning);
  }
  .circle-3 {
    background-color: var(--elp-color-primary);
  }
  .circle-4 {
    background-color: var(--elp-color-info);
  }
}
:deep(.tag_1) {
  background-color: rgba(246, 43, 20, 0.1);
}
:deep(.tag_2) {
  background-color: rgba(255, 144, 0, 0.1);
}
:deep(.tag_3) {
  background-color: rgba(0, 95, 255, 0.1);
}
:deep(.tag_4) {
  background-color: rgba(174, 182, 194, 0.1);
}
:deep(.active) {
  .calendar-title {
    span {
      color: var(--elp-color-success);
    }
  }
}
:deep(.fiz-eim-dialog) {
  .dialog-custom {
    background-color: var(--elp-bg-color-page);
  }
}
.trigger {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
}
</style>
